﻿/// ===========================================================================
/// THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
/// KIND, WHETHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
/// IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
/// PURPOSE.
/// ===========================================================================
/// 
/// Project:        Connected Lookup
/// Author:         Leonid Lyublinski 
/// Date:           07/01/2007  Version:        1.0
///
/// ===========================================================================

using System;
using System.Runtime.InteropServices;
using System.Security.Permissions;
using System.Xml;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using Microsoft.SharePoint.Security;
using Microsoft.SharePoint.Utilities;
using System.Threading;

namespace MayaIntl.SharePoint.ApplicationPages
{
    public class ConnectedLookupField : SPFieldLookup
    {
        #region Fields
        SPFieldCollection _fields;
        string _fieldName;
        string _displayName;
        string _typeName;
        string _parentField;
        string _schemaXml;
        bool _canBeParent;
        string _siteUrl;
        #endregion

        #region Constructors
        public ConnectedLookupField(SPFieldCollection fields, string fieldName)
            : base(fields, fieldName)
        {
            _fields = fields;
            _fieldName = fieldName;
        }

        public ConnectedLookupField(SPFieldCollection fields, string typeName, string displayName)
            : base(fields, typeName, displayName)
        {
            _fields = fields;
            _typeName = typeName;
            _displayName = displayName;
        } 
        #endregion

        #region Properties
        internal XmlNode Node
        {
            get
            {
                XmlElement el = null;
                XmlDocument field = new XmlDocument();
                if (_schemaXml == null) _schemaXml = SchemaXml;
                try
                {
                    field.LoadXml(_schemaXml);
                }
                catch (Exception)
                {
                    field.LoadXml(SPStringUtility.RemoveControlChars(_schemaXml));
                }
                el = field.DocumentElement;
                return el;
            }
        }
        
        public string ParentField
        {
            get
            {
                _parentField = GetFieldAttributeValue("ParentField");
                return _parentField;
            }
            set
            {
                _parentField = value;
                //SetCustomProperty("ParentField", _parentField);
                SetFieldAttributeValue("ParentField", _parentField);
            }
        } 
        public bool CanBeParent
        {
            get
            {
                _canBeParent = Convert.ToBoolean(GetFieldAttributeValue("CanBeParent"));
                return _canBeParent;
            }
            set
            {
                _canBeParent = value;
                //SetCustomProperty("CanBeParent", _canBeParent);
                SetFieldAttributeValue("CanBeParent", _canBeParent.ToString());
            }
        }

        public string SiteUrl
        {
            get
            {
                _siteUrl = GetFieldAttributeValue("SiteUrl");
                return _siteUrl;
            }
            set { 
                _siteUrl = value; 
                SetFieldAttributeValue("SiteUrl", _siteUrl); 
            }
        }
        #endregion

        #region Overrides
        
        public override BaseFieldControl FieldRenderingControl
        {
            //[SharePointPermission(SecurityAction.LinkDemand, ObjectModel = true)]
            get
            {
                BaseFieldControl fieldControl = new ConnectedLookupFieldControl();
                fieldControl.FieldName = this.InternalName;
                return fieldControl;
            }
        } 
        #endregion

        #region Methods
        internal void SetFieldAttributeValue(string attrName, string attrValue)
        {
            _schemaXml = Common.Utility.SetNamedStringItem(
                    Node.OwnerDocument,
                    Node,
                    attrName,
                    attrValue);
            
            try
            {
                if (GetProperty("ID") == null) // adding a new field
                    SetPropertyOnThread(attrName, attrValue);
                else                           // editing a field
                    SchemaXml = _schemaXml;               
            }
            catch (Exception ex)
            {

            }
        }
        internal string GetFieldAttributeValue(string attrName)
        {
            return Common.Utility.GetNamedStringItem(Node, attrName);
        }

        private string GetPropertyFromThread(string propName)
        {
            LocalDataStoreSlot slot = Thread.GetNamedDataSlot(propName);
            return (string)Thread.GetData(slot);
        }

        private void SetPropertyOnThread(string propName, string value)
        {
            LocalDataStoreSlot slot = Thread.GetNamedDataSlot(propName);
            Thread.SetData(slot, value);
        }
        private void CleanThreadLocalStorage()
        {
            Thread.FreeNamedDataSlot("ParentField");
            Thread.FreeNamedDataSlot("CanBeParent");
            Thread.FreeNamedDataSlot("SiteUrl");
        }
        #endregion
    }
}
